﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PersistanceLayer.Entity
{
   public class EntityRepository: IChatBoxDataRepository
    {
       private IList<IChatBoxUserData>  _users=new List<IChatBoxUserData>();

        public List<IChatBoxUserData> GetAllUsersOnline()
        {
            var context = new ChatBoxContext();

            foreach (var model in context.Users)
            {
                if(model.IsOnline)
                {
                   _users.Add(model);
                }
            }
            return new List<IChatBoxUserData>(_users);
        }

        public void ChangeIsOnlinePropertyWhenAppropriate(int thresholdInSeconds)
        {
            var context = new ChatBoxContext();
            var onlineUsers = new List<IChatBoxUserData>();
            //     tempUsers.AddRange(from user in _users let timeSpan = DateTime.Now.Subtract(user.LastSeen) where timeSpan.TotalSeconds <= thresholdInSeconds select user);
            foreach (ChatBoxUserData user in context.Users)
            {
                if (DateTime.Now.Subtract(user.LastSeen).TotalSeconds <= thresholdInSeconds)
                {
                    onlineUsers.Add(user);
                    user.IsOnline = true;
                        
                }
                else
                {
                    user.IsOnline = false;
                }
            }
            lock (_users)
            {
                _users = onlineUsers;
            }
            context.SaveChanges();

        }

        public IChatBoxUserData AddUserWhenNameIsNew(string name, double lat, double lon, string iconUrl)
        {
            return AddUserWhenNameIsNew(name, lat, lon, iconUrl, "");
        }


        public IChatBoxUserData AddUserWhenNameIsNew(string name, double lat, double lon, string iconUrl, string nickName)
        {
            var context = new ChatBoxContext();
            lock (_users)
            {
                foreach (ChatBoxUserData u in context.Users)
                {
                    if (u.Name.Equals(name))
                    {
                        if (u.IsOnline == false)
                        {
                            u.IsOnline = true;
                            UpdateLastSeen(u.Id);
                            return u;
                        }
                        else
                        {
                            return null;
                        }
                    }
                }
               
                ChatBoxUserData user = new ChatBoxUserData(name, iconUrl, true, nickName, lat, lon, true);
                context.Users.Add(user);
                context.SaveChanges();
                UpdateLastSeen(user.Id);
                return user;
            }

        }
        public void ClearUsers()
        {
            lock (_users)
            {
                var context = new ChatBoxContext();

                context.Database.ExecuteSqlCommand("DELETE FROM ChatBoxMessageDatas");
                context.SaveChanges();
                context.Database.ExecuteSqlCommand("DELETE FROM ChatBoxUserDatas");
                context.SaveChanges();
                _users.Clear();
                _messages.Clear();
            }
        }

        public void UpdateLastSeen(int id)
        {
            var context = new ChatBoxContext();
            IChatBoxUserData user = context.Users.ToList().FindLast(e => e.Id == id);
            if (user != null)
                user.SetLastSeen(DateTime.Now);
            context.SaveChanges();
        }


        public void LoginRegisteredUser(int id)
        {
            var context = new ChatBoxContext();

            foreach (IChatBoxUserData user in context.Users)
            {
                if (user.Id == id)
                {
                    user.SetLastSeen(DateTime.Now);
                    user.SetIsOnline(true);
                    _users.Add(user);
                    context.SaveChanges();
                }
            }
        }

        private static IList<IChatBoxMessageData> _messages = new List<IChatBoxMessageData>();
        public IList<IChatBoxMessageData> GetLastMessages(int id)
        {
            var context = new ChatBoxContext();
            UpdateLastSeen(id);

            if (context.Users.ToList().FindLast(e => e.Id == id) == null)
            {
                return new List<IChatBoxMessageData>();
            }
    
            var  lastMessages = context.Messages.OrderBy(e => e.Id).Skip(Math.Max(0, context.Messages.ToList().Count() - 5)).Take(5);
            var listMessages = new List<IChatBoxMessageData>();
            foreach (var m in lastMessages)
            {
                m.User = FindUser(GetAllUsersOnline(),id);
                listMessages.Add(m);
            }
            return listMessages;
        }


        public bool SendMessage(int id, string message)
        {
            var context = new ChatBoxContext();
            var user = GetAllUsersOnline().FindLast(e => e.Id == id);
            if (user == null) return false;
            else
            {
            //    _messages.Add(new ChatBoxMessageData(user, message));
                ChatBoxMessageEntity m = new ChatBoxMessageEntity();
                m.Message = message;
                m.User=new ChatBoxUserData(id,user.Name,user.IconUrl,true,user.NickName,user.PositionLatitude,user.PositionLongitude);
                m.UserId = id;
                //   message.Message = message;
          //      message.User.Id = id;
                context.Messages.Add(m);
                context.Messages.ToList().Add(new ChatBoxMessageData(user, message));
                context.SaveChanges();
                return true;
            }
        }
        private static IChatBoxUserData FindUser(IList<IChatBoxUserData> list, string name)
        {
            foreach (var user in list)
            {
                if (string.Equals(user.Name, name))
                    return user;
            }
            return null;
        }
        private static IChatBoxUserData FindUser(IList<IChatBoxUserData> list, int id)
        {
            foreach (var user in list)
            {
                if (user.Id==id)
                    return user;
            }
            return null;
        }
    }
}
